use actix_web::web::{Data, Json, Path};
use actix_web::{HttpResponse};
use crate::state::AppState;
use crate::dbaccess;
use crate::errors::MyError;
use crate::models::course::{ CreateCourse, UpdateCourse};

pub async fn new_course(app_state: Data<AppState>, new_course: Json<CreateCourse>)
                        -> Result<HttpResponse, MyError>
{
    let course: CreateCourse = new_course.try_into()?;
    dbaccess::course::course(&app_state.db, course)
        .await
        .map(|x| HttpResponse::Ok().json(x))
}

pub async fn update_course_details(
    app_state: Data<AppState>,
    params: Path<(i32, i32)>,
    update_course: Json<UpdateCourse>,
) -> Result<HttpResponse, MyError> {
    let (teacher_id, course_id) = params.into_inner();
    let course: UpdateCourse = update_course.try_into()?;
    dbaccess::course::update_course_details(&app_state.db, teacher_id, course_id, course)
        .await
        .map(|x| HttpResponse::Ok().json(x))
}

pub async fn get_course_for_teacher(app_state: Data<AppState>, params: Path<i32>)
                                    -> Result<HttpResponse, MyError>
{
    dbaccess::course::get_course_for_teacher(&app_state.db, params.into_inner())
        .await
        .map(|x| HttpResponse::Ok().json(x))
}

pub async fn delete_course(
    app_state: Data<AppState>,
    params: Path<(i32, i32)>,
) -> Result<HttpResponse, MyError> {
    let (teacher_id, course_id) = params.into_inner();
    dbaccess::course::delete_course(&app_state.db, teacher_id, course_id)
        .await
        .map(|x| HttpResponse::Ok().json(x))
}

pub async fn get_course_detail(app_state: Data<AppState>, params: Path<(i32, i32)>)
                               -> Result<HttpResponse, MyError>
{
    let (teacher_id, course_id) = params.into_inner();
    dbaccess::course::get_course_detail(&app_state.db, teacher_id, course_id)
        .await
        .map(|x| HttpResponse::Ok().json(x))
}


pub async fn get_course_all(app_state: Data<AppState>) -> Result<HttpResponse, MyError> {
    dbaccess::course::get_course_all(&app_state.db)
        .await
        .map(|x| HttpResponse::Ok().json(x))
}


#[cfg(test)]
mod test {
    use super::*;
    use actix_web::http::StatusCode;
    use std::sync::Mutex;

    #[actix_rt::test]
    async fn get_all_course_success() {}
}
